package com.zh.work.service.platform.channel.impl;


import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zh.common.entity.JSONResult;
import com.zh.common.entity.TransIntercept;
import com.zh.work.entity.StatisticalEntity;
import com.zh.work.service.platform.channel.RiskTransInterceptLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * code is far away from bug with the animal protecting
 * ┏┓　　　┏┓
 * ┏┛┻━━━┛┻┓
 * ┃　　　　　　　┃
 * ┃　　　━　　　┃
 * ┃　┳┛　┗┳　┃
 * ┃　　　　　　　┃
 * ┃　　　┻　　　┃
 * ┃　　　　　　　┃
 * ┗━┓　　　┏━┛
 * 　　┃　　　┃神兽保佑
 * 　　┃　　　┃代码无BUG！
 * 　　┃　　　┗━━━┓
 * 　　┃　　　　　　　┣┓
 * 　　┃　　　　　　　┏┛
 * 　　┗┓┓┏━┳┓┏┛
 * 　　　┃┫┫　┃┫┫
 * 　　　┗┻┛　┗┻┛
 *
 * @version 1.0
 * @Description : 风控交易日志业务实现
 * @Author : chenfei
 * @Create in : 2020/10/20 17:19
 */
@Service
public class RiskTransInterceptLogServiceImpl implements RiskTransInterceptLogService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public JSONResult<List<TransIntercept>> selectRiskTransLogPage(Page<TransIntercept> page,  String addStartTime, String addEndTime, TransIntercept param) {
        JSONResult<List<TransIntercept>> jsonResult = new  JSONResult<>();
        Query query = new Query();
        if(Objects.nonNull(param.getResult())){
            query.addCriteria(Criteria.where("result").is(param.getResult()));
        }
        if(Objects.nonNull(param.getMerchno())){
            query.addCriteria(Criteria.where("merchno").regex(param.getMerchno()));
        }
        if(Objects.nonNull(addStartTime) && Objects.nonNull(addEndTime)){
            query.addCriteria(Criteria.where("createDate").gte(addStartTime).lt(addEndTime));
        }
        query.with(new Sort(Sort.Direction.DESC , "createDate"));

        //方式2：利用mongodb分页
        Long count =  mongoTemplate.count(query, TransIntercept.class);
        query.skip((page.getCurrent() - 1) * page.getSize());
        query.limit((int) page.getSize());
        List<TransIntercept> resultData =  mongoTemplate.find(query,TransIntercept.class);
        jsonResult.setTotal(count);
        jsonResult.setData(resultData);

        return  jsonResult;
    }

    @Override
    public List<TransIntercept> selectRiskTransLogDownLoad(String addStartTime, String addEndTime, TransIntercept param) {
        Query query = new Query();
        if(Objects.nonNull(param.getResult())){
            query.addCriteria(Criteria.where("result").is(param.getResult()));
        }
        if(Objects.nonNull(param.getMerchno())){
            query.addCriteria(Criteria.where("merchno").regex(param.getMerchno()));
        }
        if(Objects.nonNull(addStartTime) && Objects.nonNull(addEndTime)){
            query.addCriteria(Criteria.where("createDate").gte(addStartTime).lt(addEndTime));
        }
        query.with(new Sort(Sort.Direction.DESC , "createDate"));
        List<TransIntercept> data =  mongoTemplate.find(query,TransIntercept.class);
        return data;
    }

    @Override
    public List<StatisticalEntity> selectStatisticsRiskTransLog() {
        Date startDate = DateUtil.beginOfYear(new Date());
        Date endDate =DateUtil.endOfYear(new Date());
        List<DateTime> dateTimes = DateUtil.rangeToList(startDate,endDate, DateField.MONTH);//获取今年的月份
        List<StatisticalEntity> data = new ArrayList<>();
        for(int i=0 ; i<dateTimes.size();i++){
            String startTime =null;
            String endTime = null;
            if(i>10){//统计最后一个月
                 startTime = dateTimes.get(i).toString();
                 endTime =  DateUtil.endOfYear(new Date()).toString();
            }else{
                 startTime = dateTimes.get(i).toString();
                 endTime = dateTimes.get(i+1).toString();
            }
            Criteria criteria = Criteria.where("createDate").gte(startTime).lt(endTime);
            Aggregation agg = Aggregation.newAggregation(
                    Aggregation.match(criteria),
                    Aggregation.match(Criteria.where("result").is(true)),
                    Aggregation.count().as("method")
            );
            Aggregation failAgg = Aggregation.newAggregation(
                    Aggregation.match(criteria),
                    Aggregation.match(Criteria.where("result").is(false)),
                    Aggregation.count().as("method")
            );
            AggregationResults<TransIntercept> results = mongoTemplate.aggregate(agg,"transIntercept",TransIntercept.class);
            AggregationResults<TransIntercept> failResult = mongoTemplate.aggregate(failAgg,"transIntercept",TransIntercept.class);
            int suNum = Objects.equals(results.getMappedResults().size(),0) ? 0 :Integer.valueOf(results.getMappedResults().get(0).getMethod()) ;
            int failNum = Objects.equals(failResult.getMappedResults().size(),0) ? 0 :Integer.valueOf(failResult.getMappedResults().get(0).getMethod()) ;
            if(!Objects.equals(0,suNum)){
                StatisticalEntity statisticalEntity = new StatisticalEntity();
                statisticalEntity.setLabel(startTime.substring(0,7));
                statisticalEntity.setType("成功");
                statisticalEntity.setValue(suNum);
                data.add(statisticalEntity);
            }
            if(!Objects.equals(0,failNum)){
                StatisticalEntity statisticalEntityFail = new StatisticalEntity();
                statisticalEntityFail.setLabel(startTime.substring(0,7));
                statisticalEntityFail.setType("失败");
                statisticalEntityFail.setValue(failNum);
                data.add(statisticalEntityFail);
            }
        }
        return  data;
    }
}
